#include <vld.h>
#include <cstdcall/cstdcall.h>

#include <cstdcall/_time.h>
#include <cstdcall/mutex.h>

#include <iostream>
#include <string>


using namespace cstdcall;
using namespace std;

//#pragma comment(lib , "cstdcallD.lib")

static void timer_do(void *arg, bool p)
{
	int		i = (int)arg;

	printf("timer is coming %d\n", i);
}

static void timer_do2(void *arg, bool p)
{
	char	*s = (char *)arg;

	printf("timer is coming %s\n", s);
}

static void test_timer_single_thread()
{
	error_t	err;
	auto timer = _time::NewTimer(_time::Second * 5, timer_do, (void *)1, err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}
	auto timer2 = _time::NewTimer(_time::Second * 2, timer_do2, (void *)"jinzhao", err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}

	Sleep(1000 * 10);
}



static int		count = 0;
sync::Mutex		mutex;


static DWORD WINAPI threadProc(LPVOID arg)
{

	int		i = 0;

	while(i < 500){
		{
			sync::MutexLockGuard	lock(mutex);
			count++;
			printf("thread id(%d) count:%d\n", GetCurrentThreadId(), count);
			i++;
		}
		Sleep(1);
	}
	return 0;
}



static void timer_do3(void *arg, bool p)
{
	static int num = 0;

	sync::MutexLockGuard	lock(mutex);
	count++;
	printf("thread id(%d) count:%d  timer\n", GetCurrentThreadId(), count);
	if (num < 100){
		num++;
		error_t	err;
		auto timer = _time::NewTimer(_time::Millisecond, timer_do3, NULL, err);
		if (err != nullptr){
			std::cout << err->what() << std::endl;
		}
	}
}

static void timer_do4(void *arg, bool p)
{
	printf("timer start\n");
	Sleep(10 * 1000);
	printf("timer end\n");
}



static void test_timer_multi_thread(int threadNum)
{
	error_t	err;
	auto timer = _time::NewTimer(_time::Second * 5, timer_do3, NULL, err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}


	for (auto i = 0; i < threadNum; i++){
		HANDLE h = CreateThread(NULL, 0, threadProc, NULL, 0, NULL);
		CloseHandle(h);
	}
}

static void test_timer_stop()
{
	error_t	err;
	auto timer = _time::NewTimer(_time::Second * 5, timer_do4, NULL, err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}


	auto timer2 = _time::NewTimer(_time::Second * 30, timer_do4, NULL, err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}


	Sleep(10 * 1000);
	timer2->Stop(err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}
	std::cout << "delete ok" << std::endl;
	timer->Stop(err);
	if (err != nullptr){
		std::cout << err->what() << std::endl;
		return ;
	}
	std::cout << "delete ok" << std::endl;

	Sleep(1000 * 60);

}


int main()
{
	test_timer_single_thread();
	test_timer_multi_thread(6);

	test_timer_stop();


}